package fm.realm;

import com.alibaba.fastjson.JSON;
import com.tencent.common.RandomStringGenerator;
import fm.cache.RoleCache;
import fm.dto.NeiyiUser;
import fm.exception.BizException;
import fm.mongoService.UserService;
import fm.sys.token.ClientUserToken;
import fm.sys.token.WebUserToken;
import fm.util.CommonUtils;
import fm.util.Constant;
import fm.web.CurrentRequest;
import fm.yichenet.mongo.service.SmsService;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpSession;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * Created by CM on 2015/9/3.
 */
public class ClientRealm extends AuthorizingRealm {
    private static Logger LOGGER = LoggerFactory.getLogger(ClientRealm.class);

    @Autowired
    HttpSession session;

    //    @Autowired
//    fm.mongoService.UserService userService;
    @Autowired
    UserService userService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        try {
            LOGGER.info("checking authorization information : {}", principalCollection.getPrimaryPrincipal());
            NeiyiUser user = (NeiyiUser) CurrentRequest.getCurrentUser();
            List<String> roles = RoleCache.getPermision("ClientUser" + user.getUserType());
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.addRoles(roles);
            LOGGER.info("authorization finish ,info: {}", JSON.toJSONString(info));
            return info;
        } catch (Exception ex) {
            LOGGER.error("authorization failed :", ex);
            return null;
        }
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws
            AuthenticationException {
        NeiyiUser user = null;
        SimpleAuthenticationInfo info = null;

        try {
            if (authenticationToken instanceof WebUserToken) {
                WebUserToken token = (WebUserToken) authenticationToken;
                //token 包含ID phone 验证账号存在？ 存在则登录 不存在抛出异常
                String phone = token.getPhone();
                String id = token.getId();

                user = userService.getUserByPhone(phone);
                try {
                    if (user != null) {
                        info = new SimpleAuthenticationInfo(token.getPhone(), token.getWebappName(), getName());
                    }
                } catch (Exception ex) {
                    LOGGER.error("登录授权失败:", ex);
                    throw new AuthenticationException(ex);

                }

//                else {
//                    LOGGER.info("user login:{}", StringUtils.isNotBlank(user.getName()) ? user.getName() : user.getId());
//                }


//                if (userService.checkSms(phone, vrcd)) {
//                    user = userService.getUserByPhone(phone);
//                    if (user == null) {
//                        //TODO 用手机号码登录的新用户 自动创建用户并返回登录成功信息
//                        //web_xxxxxxxx
//                        user.setPhone(phone);
//                        user.setUserType(1);
//                        //随机字符串，不长于32 位
//                        String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
////                        String randomStr= RandomStringGenerator.getRandomStringByLength(8);
//                        String userName = "web_" + randomStr;
//                        user.setAppwebName(userName);
//
//                        userService.addUser(user);
//                        user = userService.getUserByPhone(phone);
//                    }
//                    else{
//                        String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
//                        String userName = "web" + randomStr;
//                        user.setAppwebName(userName);
//                    }
//                }
//                info = new SimpleAuthenticationInfo(token.getPhone(), token.getCredentials(), getName());

            } else if (authenticationToken instanceof ClientUserToken) {

                ClientUserToken token = (ClientUserToken) authenticationToken;

                String account = token.getId();

                if (StringUtils.isNotEmpty(account)) {
                    user = userService.getById(account);
                } else {
                    account = token.getOpenid();
                    user = userService.getUserByOpenId(token.getOpenid());
                }

                if (CommonUtils.isEmpty(user)) {
                    LOGGER.info("Authentication finish, user information query failed,query user information from tencent!");
                    throw new UnknownAccountException("用户信息尚未拉取，授权失败!");
                } else {
                    LOGGER.info("user login:{}", StringUtils.isNotBlank(user.getName()) ? user.getName() : user.getId());
                }


                info = new SimpleAuthenticationInfo(account, user.getOpenid(), getName());
            }


        } catch (Exception ex) {
            LOGGER.error("登录授权失败:", ex);
            throw new AuthenticationException(ex);
        }
        session.setAttribute(Constant.SESSION_LOGIN_USER, user);


        return info;

    }

    /**
     * 添加token支持
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        if (token instanceof ClientUserToken) {
            LOGGER.info("wechat browser client authentication token! support!");
            return true;
        } else if (token instanceof WebUserToken) {
            LOGGER.info("web browser client authentication token! support!");
            return true;
        } else {
            LOGGER.info("unknown authentication token!");
            return super.supports(token);
        }
    }
}
